home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / LIBRARY / OGRID110 / GLLSTR.PAS < prev    next >
Pascal/Delphi Source File  |  1995-06-01  |  9KB  |  255 lines

  1. {*****************************************************************************
  2.  
  3.   OOGrid Library(TM) for Borland/Turbo Pascal (Real Mode/TV)
  4.   Copyright (C) 1994, 1995 by Arturo J. Monge
  5.   Portions Copyright (C) 1989,1990 Borland International, Inc.
  6.  
  7.   Borland's long strings unit:
  8.     This is Borland's TCLSTR.PAS unit with some minor
  9.     modifications necessary for adapting the LString object for
  10.     use by the TSpreadSheet object.
  11.  
  12.   Copyright (C) 1989,1990 Borland International, Inc.
  13.  
  14.   Last Modification : December 29th, 1994
  15.  
  16. *****************************************************************************}
  17.  
  18. unit GLLStr;
  19.  
  20. {$O+,F+}
  21.  
  22. {****************************************************************************}
  23.                                  interface
  24. {****************************************************************************}
  25.  
  26. uses Objects;
  27.  
  28. const
  29.   MaxLStringLength = 65521;  { The maximum amount that can be allocated
  30.                                to a pointer }
  31.  
  32. type
  33.   LStringRange = 0..MaxLStringLength;
  34.   LStringData = array [1..MaxLStringLength] of Char;
  35.   PLStringData = ^LStringData;
  36.   PLString = ^LString;
  37.   LString = object(TObject)
  38.     Len : LStringRange;        { Current length }
  39.     MaxLen : LStringRange;     { Length that has been allocated.  This is
  40.                                  always allocated in blocks of 16 bytes so
  41.                                  that the long string's data doesn't have to
  42.                                  be reallocated every time the long string
  43.                                  grows }
  44.     Data : PLStringData;
  45.     constructor Init;
  46.     destructor Done; VIRTUAL;
  47.     function SetValue(NewLen : LStringRange; NewData : Pointer) : Boolean;
  48.     function FromString(S : String) : Boolean;
  49.     function ToString : String;
  50.     function Length : LStringRange;
  51.     function Copy(Start, Amt : LStringRange) : String;
  52.     function Insert(S : String; Start : LStringRange) : Boolean;
  53.     procedure Delete(Start, Amt : LStringRange);
  54.     function Append(S : String) : Boolean;
  55.     procedure Change(Ch : Char; Start : LStringRange);
  56.     function Assign(LS : LString) : Boolean;
  57.     constructor Load(var S : TStream);
  58.     procedure Store(var S : TStream);
  59.   end;
  60.  
  61.  
  62. {****************************************************************************}
  63.                                implementation
  64. {****************************************************************************}
  65.  
  66. uses TCUtil;
  67.  
  68. constructor LString.Init;
  69. { Initializes the long string. }
  70. begin
  71.   TObject.Init;
  72.   Len := 0;
  73.   MaxLen := 0;
  74.   Data := nil;
  75. end; { LString.Init }
  76.  
  77. destructor LString.Done;
  78. { Frees memory used by the long string. }
  79. begin
  80.   if Data <> nil then
  81.     FreeMem(Data, MaxLen);
  82.   TObject.Done;
  83. end; { LString.Done }
  84.  
  85. function LString.SetValue(NewLen : LStringRange;
  86.                           NewData : Pointer) : Boolean;
  87. { Copies an area of memory to the long string }
  88. var
  89.   Size : Word;
  90.   NData : Pointer;
  91. begin
  92.   Size := (NewLen + 15) shr 4 shl 4;   { Calculate the new size }
  93.   if NewLen > MaxLen then        { Allocate new data area if the long string }
  94.   begin                          { needs to grow }
  95.     GetMem(NData, Size);
  96.     if NData = nil then          { The allocation failed.  Return False }
  97.     begin
  98.       SetValue := False;
  99.       Exit;
  100.     end;
  101.     if Data <> nil then          { If there was any data in the long string, }
  102.     begin                        { copy it to the new data area }
  103.       Move(Data^, NData^, Len);
  104.       FreeMem(Data, MaxLen);     { Free the memory used by the long string }
  105.     end;                         { before it was reallocated }
  106.     Data := NData;               { Set Data and MaxLen to their new values }
  107.     MaxLen := Size;
  108.   end;
  109.   Move(NewData^, Data^, NewLen); { Copy the new data to the long string }
  110.   Len := NewLen;                 { Set the length }
  111.   SetValue := True;              { Successful - Return True }
  112. end; { LString.SetValue }
  113.  
  114. function LString.FromString(S : String) : Boolean;
  115. { Converts a string into a long string }
  116. begin
  117.   if not SetValue(System.Length(S), @S[1]) then
  118.   begin                              { Set the long string to be a null }
  119.     FromString := SetValue(0, nil);  { string if it could not be expanded }
  120.     FromString := False;             { Return False }
  121.   end
  122.   else
  123.     FromString := True;              { Successful.  Return True }
  124. end; { LString.FromString }
  125.  
  126. function LString.ToString : String;
  127. { Converts a long string into a string }
  128. var
  129.   S : String;
  130.   NewLen : Byte;
  131. begin
  132.   NewLen := Min(255, Length);   { The maximum length of a string is 255 }
  133.   S[0] := Chr(NewLen);          { Set the length of the new string }
  134.   Move(Data^, S[1], NewLen);    { Copy the data }
  135.   ToString := S;                { Return the new string }
  136. end; { LString.ToString }
  137.  
  138. function LString.Length : LStringRange;
  139. { Returns the current length of a long string }
  140. begin
  141.   Length := Len;
  142. end; { LString.Length }
  143.  
  144. function LString.Copy(Start, Amt : LStringRange) : String;
  145. { Copies part of a long string into a string }
  146. var
  147.   S : String;
  148. begin
  149.   if Start > Len then      { Trying to copy past the end of the long }
  150.     Amt := 0               { string - return a null string }
  151.   else
  152.     Amt := Min(Amt, Succ(Len - Start));   { Calculate length of new string }
  153.   S[0] := Chr(Amt);                  { Set length of new string }
  154.   Move(Data^[Start], S[1], Amt);     { Copy data into new string }
  155.   Copy := S;                         { Return new string }
  156. end; { LString.Copy }
  157.  
  158. function LString.Insert(S : String; Start : LStringRange) : Boolean;
  159. { Inserts a string into a long string }
  160. var
  161.   OldLen : LStringRange;
  162.   Size : Word;
  163.   NData : Pointer;
  164. begin
  165.   OldLen := Len;
  166.   Inc(Len, System.Length(S));
  167.   if Len > MaxLen then               { Allocate new data area if the long }
  168.   begin                              { string needs to grow }
  169.     Size := (Len + 15) shr 4 shl 4;  { Calculate the new size }
  170.     GetMem(NData, Size);             { Allocate new data area }
  171.     if NData = nil then              { The long string could not be expanded }
  172.     begin
  173.       Dec(Len, System.Length(S));    { Restore the old Len value }
  174.       Insert := False;               { Return False }
  175.       Exit;
  176.     end;
  177.     if Data <> nil then              { If there was data in the long string, }
  178.     begin                            { copy it to the new data area }
  179.       Move(Data^, NData^, OldLen);
  180.       FreeMem(Data, MaxLen);         { Free the old data area }
  181.     end;
  182.     Data := NData;                   { Set new values for Data and MaxLen }
  183.     MaxLen := Size;
  184.   end;
  185.   if Start <= OldLen then  { Move the part of the string after the insert to }
  186.                            { the right to make space for the new string }
  187.     Move(Data^[Start], Data^[Start + System.Length(S)], Succ(OldLen - Start));
  188.   Move(S[1], Data^[Start], System.Length(S));   { Insert the new string }
  189.   Insert := True;                { Successful - return True }
  190. end; { LString.Insert }
  191.  
  192. procedure LString.Delete(Start, Amt : LStringRange);
  193. { Deletes part of a long string }
  194. begin
  195.   Amt := Min(Amt, Succ(Len - Start));  { No characters can be deleted past 
  196.                                          the end of the long string }
  197.   if Start + Amt <= Len then  { The delete is in the middle of the long
  198.                                 string - move the rest of the data to the
  199.                                 left }
  200.     Move(Data^[Start + Amt], Data^[Start], Succ(Len - Amt - Start));
  201.   Dec(Len, Amt);              { Fix the length value }
  202. end; { LString.Delete }
  203.  
  204. function LString.Append(S : String) : Boolean;
  205. { Appends a string to a long string }
  206. begin
  207.   Append := Insert(S, Succ(Len));   { Insert the string at the end }
  208. end; { LString.Append }
  209.  
  210. procedure LString.Change(Ch : Char; Start : LStringRange);
  211. { Change a particular character of a long string }
  212. begin
  213.   Move(Ch, Data^[Start], 1);
  214. end; { LString.Change }
  215.  
  216. function LString.Assign(LS : LString) : Boolean;
  217. { Copy one long string to another one }
  218. begin
  219.   Assign := SetValue(LS.Length, LS.Data);
  220. end; { LString.Assign }
  221.  
  222. constructor LString.Load(var S : TStream);
  223. { Read a long string from a stream }
  224. var
  225.   Counter, NewLen, Size : Word;
  226.   Dummy : Byte;
  227.   NData : Pointer;
  228. begin
  229.   Init;
  230.   S.Read(NewLen, SizeOf(NewLen));     { Read the length }
  231.   Size := (NewLen + 15) shr 4 shl 4;  { Calculate the new size }
  232.   if NewLen > MaxLen then       { Allocate new data area if the long string }
  233.   begin                         { needs to grow }
  234.     GetMem(NData, Size);
  235.     if NData = nil then         { The allocation failed.  Return False }
  236.     begin
  237.       for Counter := 1 to NewLen do  { Read the string in so that the file }
  238.         S.Read(Dummy, 1);            { position is still correct }
  239.       Exit;
  240.     end;
  241.     Data := NData;              { Set new values for Data and MaxLen }
  242.     MaxLen := Size;
  243.   end;
  244.   S.Read(Data^, NewLen);        { Read the long string from the stream }
  245.   Len := NewLen;
  246. end; { LString.Load }
  247.  
  248. procedure LString.Store(var S : TStream);
  249. { Write a long string to a stream }
  250. begin
  251.   S.Write(Len, SizeOf(Len));    { Write the length }
  252.   S.Write(Data^, Len);          { Write the long string }
  253. end; { LString.Store }
  254.  
  255. end.